﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SGT_DAL._STG_DALTableAdapters;
using SGT_DAL;

namespace SGT_ON
{
    /// <summary>
    /// Clase utilizada para la presentación y propiedades derivadas.
    /// </summary>
    public partial class ONLineaDeTiempo
    {
        
    }
    /// <summary>
    /// Clase base con la lógica de negocio
    /// </summary>
    [System.ComponentModel.DataObject]
    public partial class ONLineaDeTiempo
    {
        #region Atributos
        protected int _id;
        protected DateTime _fechadeInicio;
        protected int _presupuestoId;
        protected ONPresupuesto _presupuesto;
        
        //Objetos asociados
        protected ONTareaLineaDeTiempoColeccion _tareas;
        #endregion

        #region Propiedades
        public int ID
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
            }
        }
        public DateTime FechaDeInicio
        {
            get
            {
                return _fechadeInicio;
            }
            set
            {
                _fechadeInicio = value;
            }
        }
        public int PresupuestoId
        {
            get
            {
                return _presupuestoId;
            }
            set
            {
                _presupuestoId = value;
            }
        }
        
        //Objetos asociados
        public ONTareaLineaDeTiempoColeccion Tareas
        {
            get
            {
                if (_tareas != null)
                    return _tareas;

                _tareas = ONTareaLineaDeTiempo.ObtenerTodosLosTareaLineaDeTiemposDAL(this.ID);
                return _tareas;
            }
            set
            {
                _tareas = value;
            }
        }
        public ONPresupuesto Presupuesto
        {
            get
            {
                if ((_presupuesto == null)
                    || (_presupuesto.ID != PresupuestoId))
                    _presupuesto = ONPresupuesto.CrearPresupuesto(PresupuestoId);

                return _presupuesto;
            }
        }
 

        //Propiedades derivadas

        
        #endregion

        #region Interfase DAL
        //objeto de la capa DAL
        private static LineaDeTiempoTableAdapter _lineaDeTiempoAD;
        protected static LineaDeTiempoTableAdapter Adaptador
        {
            get
            {
                if (_lineaDeTiempoAD == null)
                    _lineaDeTiempoAD = new LineaDeTiempoTableAdapter();

                return _lineaDeTiempoAD;
            }
        }
        protected static ONLineaDeTiempo ObtenerPorID(int pID)
        {   
            _STG_DAL.LineaDeTiempoDataTable _dt;

            _dt = Adaptador.ObtenerPorId(pID);

            // si tiene algo,
            if (_dt.Rows.Count > 0)
                return AsignarRowAObjeto((_STG_DAL.LineaDeTiempoRow)_dt.Rows[0]);

            return null;
        }
        protected static ONLineaDeTiempo AsignarRowAObjeto(_STG_DAL.LineaDeTiempoRow pRow)
        {
            ONLineaDeTiempo _lineaDeTiempo = new ONLineaDeTiempo();
            if (pRow != null)
            {
                _lineaDeTiempo = new ONLineaDeTiempo();
                _lineaDeTiempo.ID = pRow.ID;
                _lineaDeTiempo.FechaDeInicio = pRow.FechaDeInicio;
                _lineaDeTiempo.PresupuestoId= pRow.PresupuestoId;
            }
            return _lineaDeTiempo;
        }
        protected ONLineaDeTiempo InsertarDAL(DateTime pFechaDeInicio,int pPresupuestoId)
        {
            ID = int.Parse(Adaptador.Insertar(pFechaDeInicio, pPresupuestoId).ToString());
            return this;
        }
        protected bool ActualizarDAL(DateTime pFechaDeInicio, int pPresupuestoId, int pId)
        {
            if (0 < Adaptador.Actualizar(pFechaDeInicio, pPresupuestoId, pId))
                return true;
            else
                return false;
        }
        public void EliminarDAL(int pID)
        {
            Adaptador.Eliminar(pID);
        }
        protected static ONLineaDeTiempoColeccion AsignarLineaDeTiempoTableAdapterALineaDeTiempoColeccion(_STG_DAL.LineaDeTiempoDataTable pDataTable)
        {
            ONLineaDeTiempoColeccion _lineasDeTiempo = new ONLineaDeTiempoColeccion();
            ONLineaDeTiempo _lineaDeTiempo;

            if ((pDataTable != null)
                && (pDataTable.Rows.Count > 0))
            {
                foreach (_STG_DAL.LineaDeTiempoRow _row in pDataTable.Rows)
                {
                    _lineaDeTiempo = AsignarRowAObjeto(_row);
                    if (_lineaDeTiempo != null)
                        _lineasDeTiempo.Add(_lineaDeTiempo);
                }
            }
            return _lineasDeTiempo;
        }
        //public static ONLineaDeTiempoColeccion ObtenerTodosLosLineasDeTiempoDAL()
        //{
        //    return AsignarLineaDeTiempoTableAdapterALineaDeTiempoColeccion(Adaptador.ObtenerTodos());
        //}

        #endregion



        #region Métodos
        public ONLineaDeTiempo()
        {
            AsignarValoresIniciales();
        }
        public static ONLineaDeTiempo ObtenerPorPresupuestoID(int pPresupuestoId)
        {
            _STG_DAL.LineaDeTiempoDataTable _dt;

            _dt = Adaptador.ObtenerLineaDeTiempoPorPresupuestoId(pPresupuestoId);

            // si tiene algo,
            if (_dt.Rows.Count > 0)
                return AsignarRowAObjeto((_STG_DAL.LineaDeTiempoRow)_dt.Rows[0]);

            return null;
        }
        public void AsignarValoresIniciales()
        {
            _id = -1;
            FechaDeInicio = Parametros.FechaMinima;
            PresupuestoId = -1;
        }

        public static ONLineaDeTiempo CrearLineaDeTiempo()
        {
            ONLineaDeTiempo _lineaDeTiempo = new ONLineaDeTiempo();
            return _lineaDeTiempo;
        }
        public static ONLineaDeTiempo CrearLineaDeTiempo(int pID)
        {
            ONLineaDeTiempo _lineaDeTiempo = ObtenerPorID(pID);
            return _lineaDeTiempo;
        }
        public ONLineaDeTiempo Insertar()
        {
            return InsertarDAL(FechaDeInicio, PresupuestoId);
        }
        public bool Actualizar()
        {
            return ActualizarDAL(FechaDeInicio, PresupuestoId, ID);
        }
        #endregion

        #region Metodos para datasource
        public void Actualizar(ONLineaDeTiempo pLineaDeTiempo)
        {
            if (pLineaDeTiempo != null)
                pLineaDeTiempo.Actualizar();
        }
        public ONLineaDeTiempo Insertar(ONLineaDeTiempo pLineaDeTiempo)
        {
            if (pLineaDeTiempo != null)
                return pLineaDeTiempo.Insertar();
            return null;
        }
        public void Eliminar(ONLineaDeTiempo pLineaDeTiempo)
        {

            pLineaDeTiempo.EliminarDAL(pLineaDeTiempo.ID);
        }
        #endregion

        #region Métodos del Negocio
        /// <summary>
        /// Genera una linea de tiempo para el presupuesto indicado devolviendo la linea de tiempo.
        /// </summary>
        /// <param name="pPresupuestoId"></param>
        /// <returns></returns>
        public static ONLineaDeTiempo CrearLineaDeTiempoParaPresupuesto(int pPresupuestoId)
        {
            //Obtengo los elementos para crear las tareas de la linea de tiempo
            ONElementoColeccion _elementos = ONElemento.ObtenerElementosParaCrearLineaDeTiempo(pPresupuestoId);

            ONLineaDeTiempo _lineaDeTiempo = new ONLineaDeTiempo();
            _lineaDeTiempo.PresupuestoId = pPresupuestoId;
            _lineaDeTiempo = _lineaDeTiempo.Insertar();

            ONTareaLineaDeTiempoColeccion _tareas = new ONTareaLineaDeTiempoColeccion();
            ONTareaLineaDeTiempo _tareaLT;
            
            foreach (ONElemento _elemento in _elementos)
            {
                _tareaLT = new ONTareaLineaDeTiempo();
                _tareaLT.ElementoId = _elemento.ID;
                _tareaLT.Estado = ONTareaLineaDeTiempo.EstadoInicial;
                _tareaLT.LineaDeTiempoId = _lineaDeTiempo.ID;
                _tareaLT.Nombre = _elemento.Item;
                _tareaLT.Observaciones = "";
                //asignarle el sector correcto y si tiene mas de un tilde, crearlo mas de una vez.
                if (_elemento.Reacondicionar == true)
                    _tareaLT.SectorId = Parametros.SectorIdChaperia;
                else if ((_elemento.Pintar == true)
                    || (_elemento.Reponer == true))
                    _tareaLT.SectorId = Parametros.SectorIdPintura;
                else
                    _tareaLT.SectorId = Parametros.SectorIdTaller;                
                _tareaLT.TiempoEstimadoHoras = 0;
                _tareas.Add(_tareaLT);

                //Verifico si el elemento esta seleccionado para chaperia y para pintura juntos
                // entonces lo tengo que dar de alta dos veces, la segunda si o si es pintura
                if((_elemento.Reacondicionar == true)
                    && ((_elemento.Pintar == true)
                    || (_elemento.Reponer == true)))
                {
                    _tareaLT.SectorId = Parametros.SectorIdPintura;
                    _tareas.Add(_tareaLT);
                }
            }

            //una vez que termino de crear las tareas inicialmente, las ordeno por el sector al que pertenece.
            _tareas.OrdenarPorSector();

            //ahora les asigno el orden a los elementos y le agrego los elementos fijos.
            int _orden = 0;
            ONTareaLineaDeTiempoColeccion _resultado = new ONTareaLineaDeTiempoColeccion();

            //creo la tarea de Desarmado es la tarea que va siempre primero
            _tareaLT = new ONTareaLineaDeTiempo();
            _tareaLT.ElementoId = null;
            _tareaLT.Estado = ONTareaLineaDeTiempo.EstadoInicial;
            _tareaLT.LineaDeTiempoId = _lineaDeTiempo.ID;
            _tareaLT.Nombre = "Desarmado";
            _tareaLT.Orden = _orden;
            _tareaLT.SectorId = Parametros.SectorIdChaperia;
            _tareaLT.Insertar();
            _resultado.Add(_tareaLT);
            _orden = _orden + 1;

            foreach (ONTareaLineaDeTiempo _tarea in _tareas)
            {
                _tarea.Orden = _orden;
                _tarea.Insertar();
                _resultado.Add(_tarea);
                _orden = _orden + 1;
            }
                        
            //Las tareas que siguen, van al final de las que aparecen en elementos del presupuesto.
            //Agrego armado
            _tareaLT = new ONTareaLineaDeTiempo();
            _tareaLT.ElementoId = null;
            _tareaLT.Estado = ONTareaLineaDeTiempo.EstadoInicial;
            _tareaLT.LineaDeTiempoId = _lineaDeTiempo.ID;
            _tareaLT.Nombre = "Armado";
            _tareaLT.SectorId = Parametros.SectorIdChaperia;
            _tareaLT.Orden = _orden;
            _resultado.Add(_tareaLT);

            _orden = _orden + 1;

            //Agrego Lustre
            _tareaLT = new ONTareaLineaDeTiempo();
            _tareaLT.ElementoId = null;
            _tareaLT.Estado = ONTareaLineaDeTiempo.EstadoInicial;
            _tareaLT.LineaDeTiempoId = _lineaDeTiempo.ID;
            _tareaLT.Nombre = "Lustre";
            _tareaLT.SectorId = Parametros.SectorIdPintura;
            _tareaLT.Orden = _orden;
            _resultado.Add(_tareaLT);

            _orden = _orden + 1;

            //Agrego Limpieza
            _tareaLT = new ONTareaLineaDeTiempo();
            _tareaLT.ElementoId = null;
            _tareaLT.Estado = ONTareaLineaDeTiempo.EstadoInicial;
            _tareaLT.LineaDeTiempoId = _lineaDeTiempo.ID;
            _tareaLT.Nombre = "Limpieza";
            _tareaLT.SectorId = Parametros.SectorIdTaller;
            _tareaLT.Orden = _orden;
            _resultado.Add(_tareaLT);

            _orden = _orden + 1;

            _lineaDeTiempo.Tareas = _resultado;
            return _lineaDeTiempo;
        }
        #endregion
    }
    [System.ComponentModel.DataObject]
    public class ONLineaDeTiempoColeccion : System.Collections.CollectionBase
    {
        public void Add(ONLineaDeTiempo pLineaDeTiempo)
        {
            this.List.Add(pLineaDeTiempo);
        }
        public void AddUnico(ONLineaDeTiempo pLineaDeTiempo)
        {
            foreach (ONLineaDeTiempo _lineaDeTiempo in this)
                if (pLineaDeTiempo.ID == _lineaDeTiempo.ID)
                    return;
            this.List.Add(pLineaDeTiempo);
        }
        public void Remove(int index)
        {
            if (index <= Count - 1 || index >= 0)
            {
                this.List.RemoveAt(index);
            }
            else
            {
                throw new System.ArgumentException("Fuera de rango", "original");
            }
        }
        public void Remove(ONLineaDeTiempo pLineaDeTiempo)
        {
            for (int i = 0; i < this.Count; i++)
            {
                if (this[i].ID == pLineaDeTiempo.ID)
                {
                    Remove(i);
                    return;
                }

            }
        }
        public ONLineaDeTiempo this[int index]
        {
            get { return ((ONLineaDeTiempo)(this.List[index])); }
            set { this.List[index] = value; }
        }
        public void ActualizarLineasDeTiempo(ONLineaDeTiempoColeccion pLineasDeTiempo)
        {
            foreach (ONLineaDeTiempo _lineaDeTiempo in pLineasDeTiempo)
            {
                _lineaDeTiempo.Actualizar();
            }
        }
        public void ActualizarLineaDeTiempo(ONLineaDeTiempo pLineaDeTiempo)
        {
            pLineaDeTiempo.Actualizar();
        }

        #region Metodos de colección
        
        #endregion
        #region Para datasource
        
        #endregion
    }
}
